// @flow
import React from 'react'
import styles from './DevicePoint.css'
import { Table, Select, message, InputNumber, TreeSelect, Icon, Input, Modal, notification } from 'antd'
const Option = Select.Option
import R from 'ramda'
import universalFetch, { handleFetchError } from 'store/modules/fetch'
import EditPoint from './EditPoint'
import VarComp from 'components/VarCompDeviceNew'
import Limits from 'components/LimitsDeviceNew'
import ReactDom from 'react-dom'
const TreeNode = TreeSelect.TreeNode
message.config({
  top: 100
})

type Props = {
  location: Object,
  pointData: Array<Object>,
  getPointData: Function,
  partData: Array<Object>,
  devicePoint: Array<Object>,
  deviceId: number,
  rootId: number,
  rootName: string,
  changeSelectedRows: Function
}
type States = {
  pointData: Array<Object>,
  parts: any,
  point: any,
  channelId: string,
  channelName: string,
  partDatas: Array<Object>,
  gtLimit: string,
  ggtLimit: string,
  ltLimit: string,
  gltLimit: string,
  visiblevariable: boolean,
  visibleLimit: boolean,
  varData: Array<any>,
  limitsData: Array<Object>,
  monitorPointId: string
}
class DevicePoint extends React.Component {
  state: States
  props: Props
  addPoint: Function
  changeParts: Function
  changePoint: Function
  deletePoint: Function
  selectParts: Function
  changeChannel: Function
  changeChannelName: Function
  removeEditPoint: Function
  editPoint: Function
  onChange: Function
  changeGt: Function
  changeGgt: Function
  changeLt: Function
  changeGlt: Function
  getVarData: Function
  getLimitsData: Function
  getVarLimits: Function
  handleLimitCancel: Function
  handleVarCancel: Function
  constructor (props: Props) {
    super(props)
    this.state = {
      pointData: [],
      point: '',
      channelId: '',
      channelName: '',
      parts: '',
      partDatas: [],
      gtLimit: '',
      ggtLimit: '',
      ltLimit: '',
      gltLimit: '',
      visiblevariable: false,
      visibleLimit: false,
      varData: [],
      limitsData: [],
      monitorPointId: ''
    }
    this.addPoint = this.addPoint.bind(this)
    this.changeParts = this.changeParts.bind(this)
    this.changePoint = this.changePoint.bind(this)
    this.deletePoint = this.deletePoint.bind(this)
    this.changeChannel = this.changeChannel.bind(this)
    this.changeChannelName = this.changeChannelName.bind(this)
    this.changeGt = this.changeGt.bind(this)
    this.changeGgt = this.changeGgt.bind(this)
    this.changeLt = this.changeLt.bind(this)
    this.changeGlt = this.changeGlt.bind(this)
    this.editPoint = this.editPoint.bind(this)
    this.removeEditPoint = this.removeEditPoint.bind(this)
    this.onChange = this.onChange.bind(this)
    this.getVarData = this.getVarData.bind(this)
    this.getLimitsData = this.getLimitsData.bind(this)
    this.getVarLimits = this.getVarLimits.bind(this)
    this.handleVarCancel = this.handleVarCancel.bind(this)
    this.handleLimitCancel = this.handleLimitCancel.bind(this)
  }

  componentWillReceiveProps (nextProps: Object) {
    const component = this
    if (!R.equals(nextProps, this.props)) {
      if (nextProps.partData.length > 0) {
        this.setState({ partDatas: nextProps.partData[0].children || [] })
      }
      const { deviceId } = nextProps
      this.setState({
        pointData: nextProps.pointData.map((item, index) => {
          let state = ''
          if (item.state === 0) {
            state = <span title='未同步'><Icon type='exclamation-circle-o' /></span>
          } else {
            state = <span style={{ color: '#8ec62d' }} title='已同步'><Icon type='check-circle' /></span>
          }
          return {
            key: 'pointData' + index,
            rid: item.rid,
            parts: item.deviceName,
            point: item.sensorName,
            channelId: item.channelId,
            channelName: item.channelName,
            gtLimit: item.gtLimit,
            ltLimit: item.ltLimit,
            ggtLimit: item.ggtLimit,
            gltLimit: item.gltLimit,
            state: state,
            operate: <label>
              {
                // <span
                //   className={styles['operate']}
                //   onClick={function () { component.editPoint(item) }}
                //   title='编辑测点'>
                //   <i className='fa fa-pencil-square-o' aria-hidden='true' />
                // </span>
            }
              <span
                className={styles['operateL']}
                onClick={function () { component.getVarData(deviceId, item.id) }}
                title='查看详情'>
                <i className='fa fa-table' aria-hidden='true' />
              </span>
              <span className={styles['operateL']} title='删除测点'
                onClick={function () { component.deletePoint(item) }}>
                <i className='fa fa-minus-circle' aria-hidden='true' />
              </span>
            </label>
          }
        })
      })
    }
  }
// 阈值编辑和删除后的更新函数
  getLimitsData (data: Object) {
    const { monitorPointId } = this.state
    universalFetch(`${__SERVICE_API__}device/devices/monitors/limits?monitorPointId=${monitorPointId}` +
    `&variableId=${data.variableId}`)
      .then(res => res.json())
      .then((json) => {
        if (json.code !== 200000) {
          throw new Error(JSON.stringify({ code: json.code, message: json.message }))
        }
        this.setState({
          limitsData: json.result
        })
      })
      .catch((error) => {
        handleFetchError(error)
        console.error(error)
      })
  }
  getVarData (deviceId: string, monitorPointId: string) {
    const url = `${__SERVICE_API__}device/devices/monitors/variables` +
      `?deviceId=${deviceId}&monitorPointId=${monitorPointId}`
    universalFetch(url)
      .then(res => res.json())
      .then((json) => {
        if (json.code !== 200000) {
          throw new Error(JSON.stringify({ code: json.code, message: json.message }))
        }
        this.setState({
          visiblevariable: true,
          varData: json.result,
          monitorPointId: monitorPointId
        })
      })
      .catch((error) => {
        handleFetchError(error)
        console.error(error)
      })
  }
  getVarLimits (data: Object) {
    universalFetch(`${__SERVICE_API__}device/devices/monitors/limits?` +
      `variableId=${data.id}&monitorPointId=${data.monitorPointId}`)
      .then(res => res.json())
      .then((json) => {
        if (json.code !== 200000) {
          throw new Error(JSON.stringify({ code: json.code, message: json.message }))
        }
        this.setState({
          visibleLimit: true,
          limitsData: json.result,
          monitorPointId: data.monitorPointId
        })
      })
      .catch((error) => {
        handleFetchError(error)
        console.error(error)
      })
  }
  handleVarCancel () {
    this.setState({
      visiblevariable: false
    })
  }
  handleLimitCancel () {
    this.setState({
      visibleLimit: false
    })
  }

  removeEditPoint () {
    const container = this.refs.editPoint
    ReactDom.unmountComponentAtNode(container)
  }

  deletePoint (item: Object) {
    const { getPointData } = this.props
    universalFetch(`${__SERVICE_API__}device/devices/points/${item.rid}`, {
      method: 'Delete'
    })
    .then(res => res.json())
    .then((json) => {
      if (json.code !== 200000) {
        throw new Error(JSON.stringify({ code: json.code, message: json.message }))
      }
      message.success('测点删除成功')
      getPointData()
    })
    .catch((error) => {
      handleFetchError(error)
      console.error(error)
      message.error('测点删除失败 ')
    })
  }

  editPoint (item: Object) {
    const { getPointData, partData, devicePoint, deviceId } = this.props
    const container = this.refs.editPoint
    ReactDom.render(
      <EditPoint {...{
        deviceId,
        partData,
        devicePoint,
        refreshPoint: getPointData,
        data: item,
        removeNode: this.removeEditPoint
      }} />,
    container
    )
  }

  changePoint (value: any) {
    this.setState({
      point: value
    })
  }
  changeParts (value: any) {
    this.setState({
      parts: value
    })
  }
  changeChannel (value: any) {
    this.setState({
      channelId: value
    })
  }
  changeChannelName (e: any) {
    this.setState({
      channelName: e.target.value
    })
  }
  changeGt (value: any) {
    this.setState({
      gtLimit: value
    })
  }
  changeGgt (value: any) {
    this.setState({
      ggtLimit: value
    })
  }
  changeLt (value: any) {
    this.setState({
      ltLimit: value
    })
  }
  changeGlt (value: any) {
    this.setState({
      gltLimit: value
    })
  }

  addPoint () {
    const { parts, point, channelId, channelName, gtLimit, ggtLimit, ltLimit, gltLimit } = this.state
    const { rootId, getPointData } = this.props
    if (parts && point) {
      const postData = {
        gtLimit: gtLimit,
        ltLimit: ltLimit,
        ggtLimit: ggtLimit,
        gltLimit: gltLimit,
        channelId: channelId,
        channelName: channelName,
        deviceId: parts,
        monitorPointId: point.slice(0, point.indexOf('&')),
        rootId: rootId
      }
      universalFetch(`${__SERVICE_API__}device/devices/points`, {
        method: 'POST',
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(postData)
      })
      .then(res => res.json())
      .then((json) => {
        if (json.code !== 200000) {
          notification.error({
            message: '提醒',
            description: json.message,
            placement: 'topRight',
            top: 63
          })
          throw new Error(JSON.stringify({ code: json.code, message: json.message }))
        }
        getPointData()
        message.success('测点添加成功')
      })
      .catch((error) => {
        handleFetchError(error)
        message.error('测点添加失败' + error.message)
      })
    } else {
      message.error('请选择部件和测点！')
    }
  }
  onChange (value: any) {
    this.setState({ parts: value })
  }
  render () {
    const component = this
    const { devicePoint, deviceId, rootName } = this.props
    const { pointData, partDatas, visiblevariable, visibleLimit, varData, limitsData, monitorPointId } = this.state
    const columns = [{
      title: '部件',
      dataIndex: 'parts',
      key: 'parts',
      width: '15%'
    }, {
      title: '测点',
      dataIndex: 'point',
      key: 'point',
      width: '15%'
    }, {
      title: '通道ID',
      dataIndex: 'channelId',
      key: 'channelId',
      width: '7%'
    }, {
      title: '通道名称',
      dataIndex: 'channelName',
      key: 'channelName',
      width: '10%'
    }, {
      title: '低报',
      dataIndex: 'gtLimit',
      key: 'gtLimit',
      width: '7%'
    }, {
      title: '低低报',
      dataIndex: 'ggtLimit',
      key: 'ggtLimit',
      width: '7%'
    }, {
      title: '高报',
      dataIndex: 'ltLimit',
      key: 'ltLimit',
      width: '7%'
    }, {
      title: '高高报',
      dataIndex: 'gltLimit',
      key: 'gltLimit',
      width: '7%'
    }, {
      title: '状态',
      dataIndex: 'state',
      key: 'state',
      width: '5%'
    }, {
      title: '操作',
      dataIndex: 'operate',
      key: 'operate',
      width: '15%'
    }]
    const dataSource = [{
      key: 10000,
      parts: <span><TreeSelect
        showSearch
        style={{ width: '100%' }}
        value={this.state.parts}
        dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
        placeholder='请选择部件'
        allowClear
        treeDefaultExpandAll
        onChange={this.onChange}
      >
        <TreeNode value={deviceId} title={rootName} key={'000'} >
          {
            partDatas.map((item, indexs) => {
              return (
                <TreeNode value={item.id} title={item.name} key={indexs} >
                  {
                    item.children.map((item, index) => {
                      return <TreeNode value={item.id} title={item.name} key={indexs + '_' + index} />
                    })
                  }
                </TreeNode>
              )
            })
          }
        </TreeNode>
      </TreeSelect></span>,
      point: <span><Select showSearch
        filterOption={(input, option) => {
          return option.props.children.indexOf(input) >= 0
        }} style={{ width:'100%' }} placeholder='请选择测点' onChange={this.changePoint}>
        {
          devicePoint.map((point, index) => {
            return <Option value={point.id + '&' + point.rid} key={'point' + index}>{point.sensorName}</Option>
          })
        }
      </Select></span>,
      channelId: <span><InputNumber placeholder='通道ID'
        style={{ width:'100%' }}
        onChange={this.changeChannel} /></span>,
      channelName: <span><Input placeholder='通道名称'
        style={{ width:'100%' }}
        onChange={this.changeChannelName} /></span>,
      gtLimit: <span><InputNumber placeholder='低报'
        style={{ width:'100%' }}
        onChange={this.changeGt} /></span>,
      ggtLimit: <span><InputNumber placeholder='低低报'
        style={{ width:'100%' }}
        onChange={this.changeGgt} /></span>,
      ltLimit: <span><InputNumber placeholder='高报'
        style={{ width:'100%' }}
        onChange={this.changeLt} /></span>,
      gltLimit: <span><InputNumber placeholder='高高报'
        style={{ width:'100%' }}
        onChange={this.changeGlt} /></span>,
      operate: <label>
        <span className={styles['operate']} onClick={this.addPoint} title='保存测点'>
          <i className='fa fa-plus-circle' aria-hidden='true' />
        </span>
      </label>
    }]
    const rowSelection = {
      onChange: (selectedRowKeys, selectedRows) => {
        component.props.changeSelectedRows(selectedRows)
      },
      getCheckboxProps: record => {
        return ({
          disabled: record.key === 10000
        })
      }
    }
    return (
      <div className={styles['main']}>
        <Table
          rowSelection={rowSelection}
          columns={columns}
          pagination={false}
          dataSource={pointData.concat(dataSource)} />
        <div ref='editPoint' />
        <Modal
          title='变量详情'
          width={1000}
          visible={visiblevariable}
          onCancel={this.handleVarCancel}
          footer={null}
          >
          <VarComp {...{
            varData,
            pointData,
            deviceId,
            monitorPointId,
            refreshVar: this.getVarData,
            refreshLimit: this.getVarLimits
          }} />
        </Modal>
        <Modal
          title='阈值'
          visible={visibleLimit}
          onCancel={this.handleLimitCancel}
          footer={null}
          >
          <Limits {...{
            limitsData,
            refreshLimit: this.getLimitsData
          }} />
        </Modal>
      </div>
    )
  }
}

export default DevicePoint
